home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Sound interface for Speak Freely for Unix
-
- Designed and implemented in July of 1990 by John Walker
-
- */
-
- #include "speakfree.h"
- #include <stdio.h>
- #include <fcntl.h>
- #ifdef AUDIO_DEVICE_FILE
-
- #include <errno.h>
- #include <sys/ioctl.h>
- #define AUDIO_MIN_GAIN 0
- #define AUDIO_MAX_GAIN 255
-
- static int abuf_size;
-
- #ifdef IN_AUDIO_DEV
- #define SoundFileIn IN_AUDIO_DEV
- #else
- #define SoundFileIn "/dev/audio"
- #endif
-
- #ifdef OUT_AUDIO_DEV
- #define SoundFileOut OUT_AUDIO_DEV
- #else
- #define SoundFileOut "/dev/audio"
- #endif
-
- #ifdef sun
- #define AUDIO_CTLDEV "/dev/audioctl"
- #else
- #define AUDIO_CTLDEV "/dev/mixer"
- #endif
-
- char *devAudioInput = SoundFileIn, /* Audio device files to open. */
- *devAudioOutput = SoundFileOut, /* These can overridden by the -y */
- *devAudioControl = AUDIO_CTLDEV; /* option on sfmike and sfspeaker. */
-
- #define MAX_GAIN 100
-
- struct sound_buf {
- struct sound_buf *snext; /* Next sound buffer */
- int sblen; /* Length of this sound buffer */
- unsigned char sbtext[2]; /* Actual sampled sound */
- };
-
- /* Local variables */
- static int paudiof = -1; /* For playing */
- static int raudiof = -1; /* For recording */
- static int mode = -1;
- static int volume = 100;
-
- static char WriteFile[256]; /* For the template */
- static char ReadFile[256]; /* For the template */
-
- static short pbuf[BUFL]; /* Buffer for playing */
- static short rbuf[BUFL];
- static int audiof = -1; /* Audio device file descriptor */
- static int Audio_fd; /* Audio control port */
- #ifdef sun
- static audio_info_t Audio_info; /* Current configuration info */
- #endif
- struct sound_buf *sbchain = NULL, /* Sound buffer chain links */
- *sbtail = NULL;
- static int sbtotal = 0; /* Total sample bytes in memory */
- static int playing = FALSE; /* Replay in progress ? */
- /* static int playqsize; */ /* Output queue size */
- static int playlen = 0; /* Length left to play */
- static unsigned char *playbuf= NULL; /* Current play pointer */
- static int squelch = 0; /* Squelch value */
- extern int neverRelease = FALSE; /* Never release audio device. This
- is set if we inherited our open
- audio device file descriptor from
- a parent process. If we release
- it, there's no way we can get it
- back, so we glom onto it until
- we exit. */
-
- /* Convert local gain into device parameters */
-
- static unsigned scale_gain(g)
- unsigned g;
- {
- return (AUDIO_MIN_GAIN + (unsigned)
- ((int) ((((double) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) *
- ((double) g / (double) MAX_GAIN)) + 0.5)));
- }
-
- #ifdef Solaris
-
- /* SETAUBUFSIZE -- Preset size of internal /dev/audio buffer segments
- Must be called before soundinit() */
-
- static int aubufsize = 2048; /* Default */
-
- void setaubufsize(size)
- int size;
- {
- aubufsize = size;
- }
- #endif
-
-
- /* SOUNDINIT -- Open the sound peripheral and initialise for
- access. Return TRUE if successful, FALSE
- otherwise. */
- int soundinit(iomode)
- int iomode;
- {
- char *variable;
- int punit = 0;
- int runit = 0;
-
- /* Save mode for soundplayvol() */
- mode = iomode;
-
- if(iomode == -1) {
- return FALSE;
- }
-
- /* Find out where to read and play audio */
-
- variable = getenv("SPEAKFREE_PLAY_UNIT");
- if(variable) {
- punit = strtol(variable, NULL, 10);
- }
-
- variable = getenv("SPEAKFREE_RECORD_UNIT");
- if(variable) {
- runit = strtol(variable, NULL, 10);
- }
-
- sprintf((char *) WriteFile,
- "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
- "VOLUME/%d/BUFFER/8192/UNIT/%d", volume, punit);
- sprintf((char *) ReadFile,
- "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
- "BUFFER/2048/UNIT/%d", runit);
-
- if (iomode != O_RDONLY) {
- if ((paudiof = open(WriteFile, O_WRONLY)) < 0) {
- fprintf(stderr, "Audio open: unable to open \"%s\"\n", WriteFile);
- return FALSE;
- }
- }
-
- if (iomode != O_WRONLY) {
- if ((raudiof = open(ReadFile, O_RDONLY)) < 0) {
- fprintf(stderr, "Audio open: unable to open \"%s\"\n", ReadFile);
- return FALSE;
- }
- }
-
- return TRUE;
- }
-
- /* SOUNDTERM -- Close the sound device. */
-
- void soundterm()
- {
- if (paudiof >= 0) {
- if (close(paudiof) < 0) {
- perror("closing audio device");
- }
- paudiof = -1;
- }
- if (raudiof >= 0) {
- if (close(raudiof) < 0) {
- perror("closing audio device");
- }
- raudiof = -1;
- }
- mode = -1;
- }
-
-
- /* SOUND_OPEN_FILE_DESCRIPTORS -- Obtain file descriptors of open
- audio and audio control device files. */
-
- void sound_open_file_descriptors(audio_io, audio_ctl)
- int *audio_io, *audio_ctl;
- {
- *audio_io = audiof;
- *audio_ctl = Audio_fd;
- }
-
- /* SOUNDPLAY -- Begin playing a sound. */
-
- void soundplay(len, buf)
- int len;
- unsigned char *buf;
- {
- int ios;
- int i;
-
- if(len > BUFL) {
- len = BUFL;
- }
-
- /* Convert µlaw to 16 bit */
- for (i = 0; i < len; i++) {
- pbuf[i] = ulaw2linear(buf[i]);
- }
-
- while (TRUE) {
- ios = write(paudiof, pbuf, len << 1 );
- if (ios == -1) {
- sf_usleep(100000);
- } else {
- ios >>= 1;
- if (ios < len ) {
- buf += ios;
- len -= ios;
- } else {
- break;
- }
- }
- }
- }
-
-
- /* SOUNDPLAYVOL -- Set playback volume from 0 (silence) to 100 (full on). */
-
- void soundplayvol(value)
- int value;
- {
- volume = value;
- soundterm();
- soundinit(mode);
- }
-
-
- /* SOUNDRECGAIN -- Set recording gain from 0 (minimum) to 100 (maximum). */
-
- void soundrecgain(value)
- int value;
- {
- }
-
- /* SOUNDDEST -- Set destination for generated sound. If "where"
- is 0, sound goes to the built-in speaker; if
- 1, to the audio output jack. */
-
-
- void sounddest(where)
- int where;
- {
- }
-
- /* SOUNDGRAB -- Return audio information in the record queue. */
-
- int soundgrab(buf, len)
- char *buf;
- int len;
- {
- long read_size;
- int c;
- int i;
-
- if(len > BUFL) {
- len = BUFL;
- }
-
- read_size = len;
-
- while (TRUE) {
- c = read(raudiof, rbuf, read_size << 1);
- if (c < 0) {
- if (errno == EINTR) {
- continue;
- }
- } else {
- c >>= 1;
- }
- break;
- }
- if (c < 0) {
- perror("soundgrab");
- }
-
- /* Convert 16 bit to µlaw */
- for (i = 0; i < len; i++) {
- buf[i] = linear2ulaw(rbuf[i]);
- }
-
- return c;
- }
-
-
- /* SOUNDFLUSH -- Flush any queued sound. */
-
- void soundflush()
- {
- /*
- soundterm();
- soundinit(mode);
- */
- }
-
-
- #endif /* AUDIO_DEVICE_FILE */
-